'use strict';

const Service = require('egg').Service;
const moment = require('moment');

class CommissionService extends Service {
  async index() {
    // 查找并处理全部需要处理的订单
    const foundAllOrders = await this.findAllOrders();
    foundAllOrders.forEach(async order => {
      await this.processOrder(order);
    });
    // 发放商户收入到余额（已完成）
    const merchantIncomeLogs = await this.app.model.CommissionLog.findAll({
      status: 'pending',
    });
    const merchantUserIdAmouts = {};
    merchantIncomeLogs.forEach(async commissionLog => {
      const { userId, commission } = commissionLog;
      if (merchantUserIdAmouts[`userId${userId}`]) {
        merchantUserIdAmouts[`userId${userId}`] = commission + merchantUserIdAmouts[`userId${userId}`];
      } else {
        merchantUserIdAmouts[`userId${userId}`] = commission;
      }
    });
    for (const key in userIdAmout) {
      if (merchantUserIdAmouts.hasOwnProperty(key)) {
        const commission = merchantUserIdAmouts[key];
        const userId = key.replace(/[^0-9]/gi, '');
        const user = await this.app.model.User.findByPk(userId);
        const store = await this.app.model.Store.findOne({ where: { userId: user.id } });
        const newBalance = Number(store.balance) + commission;
        const data = {
          storeId: store.id,
          balance: newBalance,
          price: commission,
          add: true,
          remark: '商户收入发放',
        };
        await this.app.model.StoreBalanceRecord.create(data);
        await store.update({ balance: newBalance });
      }
    }
    // 发放佣金到余额（已完成）
    // 找到所有状态为 pending 的记录
    const allCommissionLogs = await this.app.model.CommissionLog.findAll({
      status: 'pending',
    });
    // 取出状态为 pending  的所有用户
    const userIdAmout = {};
    allCommissionLogs.forEach(async commissionLog => {
      const { userId, commission } = commissionLog;
      if (userIdAmout[`userId${userId}`]) {
        userIdAmout[`userId${userId}`] =
          commission + userIdAmout[`userId${userId}`];
      } else {
        userIdAmout[`userId${userId}`] = commission;
      }
    });
    for (const key in userIdAmout) {
      if (userIdAmout.hasOwnProperty(key)) {
        const commission = userIdAmout[key];
        const userId = key.replace(/[^0-9]/gi, '');
        const user = await this.app.model.User.findByPk(userId);
        const newBalance = Number(user.balance) + commission;
        const data = {
          userId: user.id,
          balance: newBalance,
          price: commission,
          add: true,
          remark: '佣金发放',
        };
        await this.app.model.BalanceRecord.create(data);
        await user.update({ balance: newBalance });
      }
    }
  }
  // 查找全部需要处理的订单
  async findAllOrders() {
    return await this.ctx.model.Order.findAll({
      createdAt: {
        [this.ctx.model.Op.between]: [
          moment().startOf('day'),
          moment().endOf('day'),
        ],
      },
    });
  }
  // 处理订单
  async processOrder(order) {
    // 定义订单总额
    const { amount: orderAmount } = order;
    // 找出商品
    const orderItem = await order.getOrderItem();
    const item = await orderItem.getItem();
    const store = await item.getStore();
    // 定义平台佣金比例
    const { commissionRatio: platformCommissionRatio } = store;
    // 计算出平台所得佣金
    const platformCommission = Math.floor(
      orderAmount * platformCommissionRatio
    );
    // 计算出商户收入
    const merchantIncome = orderAmount - platformCommission;
    await this.recordMerchantIncome(store.id, order.id, merchantIncome);

    // 定义平台收入
    let platformIncome = platformCommission;
    // 找出商家的服务商
    const facilitator = await store.getFacilitator();
    // 判断服务商存在与否
    if (facilitator) {
      // 定义服务商佣金比例
      const {
        decimal5with5: facilitatorCommissionRatio,
      } = this.ctx.model.Config.findByPk('facilitatorCommissionRatio');
      // 服务商佣金
      const facilitatorCommission = Math.floor(
        platformCommission * facilitatorCommissionRatio
      );
      // 更新平台收入
      platformIncome = platformCommission - facilitatorCommission;
    }

    // 找到会员基础佣金比例
    const {
      decimal5with5: memberCommissionRatio,
    } = this.ctx.model.Config.findByPk('memberCommissionRatio');
    // 计算会员基础佣金
    const memberBaseCommission = Math.floor(
      platformIncome * memberCommissionRatio
    );

    // 定义用户（订单实际消费者）
    const user = await order.getUser();
    // 发放团队佣金
    await this.recordGroupCommissionClassifications(
      user,
      order.id,
      memberBaseCommission
    );
  }
  // 记录商户收入(已写)
  async recordMerchantIncome(storeId, orderId, merchantIncome) {
    const data = { storeId, orderId, merchantIncome };
    await this.app.model.MerchantIncomeLog.create(data);
  }
  async recordGroupCommissionClassifications(
    user,
    orderId,
    memberBaseCommission
  ) {
    let groupCommissionClassifications = [
      {
        role: 'general',
        type: 'general', // 普通用户
      },
      {
        role: 'member',
        type: 'member', // 会员
      },
      {
        role: 'higher',
        type: 'directHigher', // 直接高级店主
        ratio: 0.2,
      },
      {
        role: 'higher',
        type: 'indirectHigher', // 间接高级店主
        ratio: 0.05,
      },
      {
        role: 'facilitator',
        type: 'directFacilitator', // 直接服务商
        ratio: 0.1,
      },
      {
        role: 'facilitator',
        type: 'indirectFacilitator', // 间接服务商
        ratio: 0.05,
      },
    ];
    const compareUserWithGroupCommissionClassification = (
      user,
      groupCommissionClassification
    ) => groupCommissionClassification.role === user.role;
    while (user) {
      const groupCommissionClassificationIndex = groupCommissionClassifications.findIndex(
        compareUserWithGroupCommissionClassification.bind(this, user)
      );
      // 找出当前团队佣金等级
      const groupCommissionClassification =
        groupCommissionClassifications[groupCommissionClassificationIndex];
      await this.recordGroupCommission(
        user,
        memberBaseCommission,
        groupCommissionClassification.type,
        groupCommissionClassificationIndex === 1
      );
      // 删除较当前团队佣金等级低的团队佣金等级
      groupCommissionClassifications = groupCommissionClassifications.slice(
        groupCommissionClassificationIndex
      );
      user = await user.getInviter();
    }
  }
  async recordGroupCommission(
    user,
    orderId,
    memberBaseCommission,
    type,
    isSameGroupCommissionClassificationWithPreviousUser
  ) {
    // 记录团队佣金（已写）
    const data = {
      userId: user.id,
      orderId,
      memberBaseCommission,
      type,
      isSameGroupCommissionClassificationWithPreviousUser,
    };
    await this.app.model.GroupCommissionLog.create(data);
    // 给指定用户添加佣金
    const typeRatio = {
      member: 1,
      directHigher: 0.2,
      indirectHigher: 0.05,
      directFacilitator: 0.1,
      indirectFacilitator: 0.05,
    };
    const ratio = typeRatio(type);
    if (ratio && !isSameGroupCommissionClassificationWithPreviousUser) {
      await this.addCommission(
        user,
        orderId,
        Math.ceil(memberBaseCommission * ratio)
      );
    }
  }
  // 给指定用户添加佣金（已写）
  async addCommission(user, orderId, commission) {
    const data = {
      price: commission,
      add: true,
      userId: user.id,
    };
    await this.app.model.BalanceRecord.create(data);
    const awardUser = await this.ap.model.User.findByPk(user.id);
    const awardUserNewBalance = Number(awardUser.balance) + commission;
    await awardUser.update({ balance: awardUserNewBalance });
  }
}

module.exports = CommissionService;
